﻿/*
 * Copyright 2014 Francois Karman
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

using Quartz.Impl.Matchers;
using Quartz.WebManager.Model;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Quartz.WebManager.Logic
{
    /// <summary>
    /// Manages all the job instances registered in the scheduler.
    /// </summary>
    public static class JobInstanceManager
    {
        /// <summary>
        /// Retrieves all the existing job instances.
        /// </summary>
        /// <returns>All the existing job instances.</returns>
        public static IEnumerable<JobInstance> RetrieveAll()
        {
            var jobKeys = Factory.GetScheduler().GetJobKeys(GroupMatcher<JobKey>.AnyGroup());
            return jobKeys.Select(k => RetrieveOne(k));
        }

        /// <summary>
        /// Retrieves all the existing job instances for a specific group.
        /// </summary>
        /// <param name="group">The name of the group.</param>
        /// <returns>All the existing job instances for the <paramref name="group"/>.</returns>
        public static IEnumerable<JobInstance> RetrieveAllForGroup(string group)
        {
            var jobKeys = Factory.GetScheduler().GetJobKeys(GroupMatcher<JobKey>.GroupEquals(group));
            return jobKeys.Select(k => RetrieveOne(k));
        }

        /// <summary>
        /// Retrieves the detail of a specific job instance.
        /// </summary>
        /// <param name="key">The key associated with the job instance.</param>
        /// <returns>The detail about the job instance.</returns>
        private static JobInstance RetrieveOne(JobKey key)
        {
            IJobDetail jobDetail = Factory.GetScheduler().GetJobDetail(key);
            JobDefinition definition = JobDefinitionManager.Cache.FirstOrDefault(d => string.Equals(d.TypeName, jobDetail.JobType.AssemblyQualifiedName, StringComparison.OrdinalIgnoreCase));
            DateTimeOffset? nextFireTime = Factory.GetScheduler().GetTriggersOfJob(key).Select(t => t.GetNextFireTimeUtc()).Where(d => d.HasValue).Min();
            JobInstance result = new JobInstance()
            {
                Group = key.Group,
                Name = key.Name,
                JobDefinition = definition.DisplayName,
                NextFireTime = nextFireTime,
            };

            return result;
        }
    }
}
